#include <stdio.h>
#include <set>
#include <mutex>
#include "thread/event_loop_thread.h"
#include "thread/event_loop_thread_pool.h"
#include "net/tcp_server.h"
#include "net/tcp_connection.h"

static rr::nio::EventLoopThread::Sptr loop_thread;
static rr::nio::EventLoopThreadPool::Sptr loop_thread_pool;

static rr::nio::TcpServer::Sptr tcp_server;

static std::mutex con_mutex;
static std::set<rr::nio::TcpConnection::Sptr> connections;

static void CloseCallback(rr::nio::TcpConnectionVar conn)
{
    printf("CloseCallback: conn[%p]\n", conn.get());

    std::lock_guard<std::mutex> lock(con_mutex);
    auto it = connections.find(conn);
    if(it != connections.end()) {
        connections.erase(it);
    } else {
        printf("CloseCallback: not found\n");
    }
}

static void ConnectionCallback(rr::nio::TcpConnectionVar conn)
{
    printf("ConnectionCallback: conn[%p]\n", conn.get());
    conn->SetCloseCallback(CloseCallback);
    std::lock_guard<std::mutex> lock(con_mutex);
    connections.insert(conn);
}

void TestTcpServerStart()
{
    if(!loop_thread) {
        loop_thread = std::make_shared<rr::nio::EventLoopThread>();
        loop_thread->StartLoop();
    }

    if(!loop_thread_pool) {
        loop_thread_pool = std::make_shared<rr::nio::EventLoopThreadPool>();
        loop_thread_pool->Start(4);
    }
    tcp_server = std::make_shared<rr::nio::TcpServer>(loop_thread->GetLoop(), loop_thread_pool);
    tcp_server->SetConnectionCallback(ConnectionCallback);

    tcp_server->Start();

    return;
}   

void TestTcpServerStop()
{
    if(tcp_server) {
        tcp_server->Stop();
        tcp_server.reset();
    }

}